#!/usr/bin/python

#from gi.repository import Gtk
#from gi.repository import Gdk
import gtk

from decimal import Decimal
import decimal
import gobject
import threading
import math

from gtkmvc import View
        
class AscensorVistaPozo(View):        
    def __init__(self, model): #, label):
        View.__init__(self)

        self.lock = threading.RLock()
        model.lock.acquire()    
        self.mainbox = gtk.HBox(spacing=4)

        self.images = dict()
        for n in [ "light_on", "light_off", "fan_on", "fan_off", "person", "go_down", "go_up", "weight" ]:
#            img = gtk.gdk.Image()
            img = gtk.gdk.pixbuf_new_from_file("images/16x16/"+n+".png")
            self.images[n] = img

        self.fpozo = gtk.Frame("Fozo:")
        self.pozo = gtk.DrawingArea()
        self.pozo.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("darkslategray"))
        self.pozo.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("forestgreen"))
        height = (int(16*3.5))*model.tope + 8
        self.pozo.set_size_request(int(16*3.5)+8, height)

        self.fpozo.add(self.pozo)
        self.mainbox.pack_start(self.fpozo)

        self.regla = gtk.Fixed()
        self.regla.set_size_request(int(16*3.5), height)
        self.mainbox.pack_start(self.regla)
        
        delta = (height-8)/model.tope        
        y = height-4
        for i in xrange(model.tope):
            l0 = gtk.Label("")
            l0.set_markup("<u>"+str(i)+"</u>")
            self.regla.put(l0,0,y)
            y -= delta            

        # Atributos.
        self["posicion"] = model.posicion
        self["nombre"] = model.nombre
        vel = model.velocidad.quantize(Decimal(".01"), rounding=decimal.ROUND_DOWN)
        self["velocidad"] = vel
        self["peso"] = Decimal(0.0)
        self["capacidad"] = int(model.capacidad)
#        self.capacidad_anterior = int(model.capacidad) 
        self.personas = 0
        self.alarma_peso = False

        self["movimiento"] = model.movimiento
        self["destino"] = model.destino
        self["pedidos"] = model.pedidos
        self["tope"] = model.tope
        self["puerta_abierta"] = model.puerta_abierta
        self["luces"] = False
        self["ventilacion"] = False

        self.abox = gtk.VBox()
        self.estado = gtk.Frame("Estado:")
        self.tabla = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
        self.vtabla = gtk.TreeView() #gtk.Table(rows=len(model.__observables__), columns=2, homogeneous=True) #gtk.VBox()

        self.celdas = {}
        for atr in ["nombre", "posicion", "velocidad", "peso", "capacidad", "movimiento", "destino", "pedidos", "tope", "puerta_abierta"]:
            it = self.tabla.append( (atr.title(), str(self[atr])) )
            self.celdas[atr] = it

        for i,nombre in [(0,"Atributo"), (1,"Valor")]:
            col = gtk.TreeViewColumn(nombre)
            self.vtabla.append_column( col )

            cel = gtk.CellRendererText()
            col.pack_start(cel)
            col.set_attributes(cel, text=i)

        selection = self.vtabla.get_selection()
        selection.connect("changed",self._ignore_clicked)
        
        self.vtabla.set_headers_visible(True)
        self.vtabla.set_rules_hint(True)

        self.vtabla.set_model(self.tabla)
        self.estado.add(self.vtabla)
        self.abox.pack_start(self.estado)

        self.controles = gtk.Frame("Controles:")
        botonera = gtk.Table(homogeneous=True)

        tope = self["tope"]
        i = 0
        for x in xrange(tope, 0, -2):
            button1 = gtk.Button(label=str(x-1))
            if x < tope:
                button2 = gtk.Button(label=str(x))

            button1.set_size_request(8,8)
            if x < tope:
                button2.set_size_request(8,8)

            botonera.attach(button1, 0, 1, i, i+1)
            if x < tope:
                botonera.attach(button2, 1, 2, i, i+1)
            x1 = None
            i += 1

        bluz = gtk.Button()
        self.imgLuz = gtk.Image()
        self.imgLuz.set_from_pixbuf(self.images["light_on"])
        bluz.add(self.imgLuz)
        botonera.attach(bluz, 0, 1, i, i+1)

        bfan = gtk.Button()
        self.imgFan = gtk.Image()
        self.imgFan.set_from_pixbuf(self.images["fan_on"])
        bfan.add(self.imgFan)
        botonera.attach(bfan, 1, 2, i, i+1)

        bluz.set_size_request(8,8)
        bfan.set_size_request(8,8)

        self["botonera"] = botonera
        self.controles.add(botonera)
#        self.abox.pack_start(self.controles)

        self.mainbox.pack_end(self.abox)

        self.selected = False

        self.pozo.add_events(gtk.gdk.BUTTON_PRESS_MASK)
        self.pozo.connect('expose_event', self.expose)
        self.pozo.connect('button_press_event', self.on_click)

        self.hermanos = set()
        model.lock.release()    

    def _ignore_clicked(self, selection):
        liststores, listpaths = selection.get_selected_rows()
        for selected_row in xrange(len(listpaths)):
            selection.unselect_path(listpaths[selected_row])

    def agregar_hermano(self, vista):
        if vista != self:
            self.hermanos.add(vista)

    def on_click(self, widget, event):
        x = event.x
        y = event.y
        
        width = self.pozo.allocation.width
        pad = self._calcular_x()
        elegir = x >= pad and x <= (width-pad)
        pos = None
        if elegir:
            pos = self._calcular_y(self["posicion"],self["tope"])
            elegir = y >= pos and y <= (pos+(int(16*3.5)))

        if elegir:
            for h in self.hermanos:
                h.selected = False
#                h.label.set_visible(False)
#                h.pozo.queue_draw()
            self.selected = not self.selected
#            self.label.set_visible(self.selected)

        self.pozo.queue_draw()
        

    def _calcular_y(self, pos, tope):
        height = self.pozo.allocation.height
        x = self._calcular_x()
        aux = int( (height-x) * (1.0 - float(pos)/tope) )
        if aux == 0:
            return x
        else:
            return aux - (int(16*3.5))

    def _calcular_x(self):
        width = self.pozo.allocation.width
        return int( (width-(int(16*3.5)))/2 )

    def update(self, prop_name, value):
        self.lock.acquire()
        if prop_name == "posicion":
            self.update_posicion(value)
#       elif prop_name == "capacidad":
#            self.update_capacidad(value)
        elif prop_name == "nombre":
            self["nombre"] = value
        elif prop_name == "destino":
            self["destino"] = value
        elif prop_name == "movimiento":
            self["movimiento"] = value
        elif prop_name == "puerta_abierta":
            self["puerta_abierta"] = value
#        elif prop_name == "peso":
#            self.update_peso(self,value)
                        
        elif prop_name == "tope":
            self["tope"] = value
#        self.__setitem__(prop_name,value)
        self.lock.release()

    def update_peso(self, peso):
        self.lock.acquire()
        if self["peso"] > peso:
            self.personas -= 1
        elif self["peso"] < peso:
            self.personas += 1
        self["peso"] = peso
        self.lock.release()

    def update_ventilacion(self, activar):
        self["ventilacion"] = activar
    def update_luces(self, activar):
        self["luces"] = activar

    def update_alarma_peso(self, alarma):
        self.lock.acquire()
        self.alarma_peso = (alarma == True)
        self.lock.release()

    def update_capacidad(self, capacidad) :
        self.lock.acquire()
        self["capacidad"] = capacidad
        self.lock.release()

    def expose(self, widget, info):
        self.lock.acquire()
        y = self._calcular_y(self["posicion"], self["tope"])
        x = self._calcular_x()
        style = self.pozo.get_style()
        gc = style.fg_gc[gtk.STATE_NORMAL]

        color = gtk.gdk.color_parse("forestgreen")
        if self.alarma_peso:
            color = gtk.gdk.color_parse("orange")
        elif self["puerta_abierta"] > 0:
            color = gtk.gdk.color_parse("blue")
        self.pozo.modify_fg(gtk.STATE_NORMAL, color)

        height = self.pozo.allocation.height

        self.pozo.window.draw_rectangle(gc, True, x, y, int(16*3.5), int(16*3.5))

        w = self.pozo.window
        if self["luces"]:
            w.draw_pixbuf(gc, self.images["light_on"], 0,0, x+1,y+1, 16,16)
        else:
            w.draw_pixbuf(gc, self.images["light_off"], 0,0, x+1,y+1, 16,16)

        if self["ventilacion"]:
            w.draw_pixbuf(gc, self.images["fan_on"], 0,0, x+18,y+1, 16,16)
        else:
            w.draw_pixbuf(gc, self.images["fan_off"], 0,0, x+18,y+1, 16,16)

        if self.alarma_peso:
            w.draw_pixbuf(gc, self.images["weight"], 0,0, x+35,y+1, 16,16)

        for i in xrange(self.personas):
            w.draw_pixbuf(gc, self.images["person"], 0,0, x+1+(18*i),y+int(16*2.5)-1, 16,16)
            
        self.vtabla.set_model(None)
        for nombre,it in self.celdas.items():
            self.tabla.set_value(it,1,self[nombre])
        self.vtabla.set_model(self.tabla)
        self.lock.release()

    def update_posicion(self, posicion):
        if posicion != int(posicion):
            if self["posicion"] < posicion:
                self["movimiento"] = "subiendo"
            if self["posicion"] > posicion:
                self["movimiento"] = "bajando"
        self["posicion"] = posicion

class EdificioVistaGtk(View):        
    def __init__(self, ascensores):
        View.__init__(self)
        
        w = gtk.Window()
        hb = gtk.HBox(spacing=6)

#        vb = gtk.VBox()
        vb = gtk.Table()
#        vb.set_size_request(480,360)

        avs = list()
        for am,av,ac in ascensores:
            avs.append(av)
            
        i = 0
        for am,av,ac in ascensores:
            if not av is None:
                for hermano in avs:
                    av.agregar_hermano(hermano)
                hb.pack_start(av.mainbox)
            i += 1


        hb.pack_end(vb)
        w.add(hb)
#        w.set_default_size(600,400)
        w.show_all()

#        for am, av, tv in ascensores:
#            if not av is None:
#                av.label.set_visible(False)

        self['main_window'] = w
        self['workspace'] = hb
        self['administracion'] = vb

    pass

if __name__ == '__main__':
    pass
